package naga.x.net.codec;

import naga.x.net.impl.websocket.WebSocketDecoder;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

public abstract class StickPacketDecoder extends ProtocolDecoderAdapter {

	protected static final String BUFFER = WebSocketDecoder.class.getName() + ".buffer";
	
	@Override
	public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
		IoBuffer buf = (IoBuffer) session.getAttribute(BUFFER);
		boolean useSessionBuffer = false;
		if (buf != null) {
			useSessionBuffer = true;
			buf.put(in);
			buf.flip();
			in = buf;
		}
		
		while (in.hasRemaining() && doDecode(session, in, out)) {
			// nothing
		}
		
		if (in.hasRemaining()) {
			if (useSessionBuffer) {
				in.compact();
			} else {
				buf = IoBuffer.allocate(in.remaining()).setAutoExpand(true).order(in.order()).put(in);
				session.setAttribute(BUFFER, buf);
			}
		} else if (useSessionBuffer) {
			session.removeAttribute(BUFFER);
		}
	}
	
	protected abstract boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception;

}
